package com.xuelang.pipeline.infrastructure.application.repository;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuelang.pipeline.client.application.dto.ApplicationQuery;
import com.xuelang.pipeline.client.common.result.PageRecord;
import com.xuelang.pipeline.domain.application.Application;
import com.xuelang.pipeline.domain.application.repository.ApplicationRepository;
import com.xuelang.pipeline.infrastructure.application.converter.ApplicationToApplicationDOConverter;
import com.xuelang.pipeline.infrastructure.application.dataobject.ApplicationDO;
import com.xuelang.pipeline.infrastructure.application.mapper.ApplicationMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 应用仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class ApplicationRepositoryImpl implements ApplicationRepository {

    @Autowired
    ApplicationMapper applicationMapper;

    @Override
    public PageRecord<Application> pageList(long currentPage, long pageSize, ApplicationQuery applicationQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<ApplicationDO> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<ApplicationDO> wrapper = Wrappers.lambdaQuery(ApplicationDO.class);
        if (applicationQuery != null) {
            if (StringUtils.isNotBlank(applicationQuery.getCode())) {
                wrapper.like(ApplicationDO::getCode, applicationQuery.getCode());
            }
            if (CollectionUtils.isNotEmpty(applicationQuery.getCodeList())) {
                wrapper.in(ApplicationDO::getCode, applicationQuery.getCodeList());
            }
            if (StringUtils.isNotBlank(applicationQuery.getName())) {
                wrapper.like(ApplicationDO::getName, applicationQuery.getName());
            }
            if (StringUtils.isNotBlank(applicationQuery.getProjectCode())) {
                wrapper.eq(ApplicationDO::getProjectCode, applicationQuery.getProjectCode());
            }
        }
        applicationMapper.selectPage(page, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords().stream().map(ApplicationToApplicationDOConverter.INSTANCE::applicationDOToApplication).collect(Collectors.toList())
        );
    }

    @Override
    public List<Application> list(ApplicationQuery applicationQuery) {
        LambdaQueryWrapper<ApplicationDO> wrapper = Wrappers.lambdaQuery(ApplicationDO.class);
        if (applicationQuery != null) {
            if (StringUtils.isNotBlank(applicationQuery.getCode())) {
                wrapper.like(ApplicationDO::getCode, applicationQuery.getCode());
            }
            if (StringUtils.isNotBlank(applicationQuery.getName())) {
                wrapper.like(ApplicationDO::getName, applicationQuery.getName());
            }
            if (StringUtils.isNotBlank(applicationQuery.getProjectCode())) {
                wrapper.eq(ApplicationDO::getProjectCode, applicationQuery.getProjectCode());
            }
            if (StringUtils.isNotBlank(applicationQuery.getUserId())) {
                wrapper.eq(ApplicationDO::getCreatorId, applicationQuery.getUserId())
                        .or()
                        .eq(ApplicationDO::getUpdaterId, applicationQuery.getUserId());
            }
        }
        return applicationMapper.selectList(wrapper).stream()
                .map(ApplicationToApplicationDOConverter.INSTANCE::applicationDOToApplication).collect(Collectors.toList());
    }

    @Override
    public Boolean save(Application application) {
        return applicationMapper.insert(ApplicationToApplicationDOConverter.INSTANCE.applicationToApplicationDO(application)) == 1;
    }

    @Override
    public Boolean update(Application application) {
        return applicationMapper.update(
                ApplicationToApplicationDOConverter.INSTANCE.applicationToApplicationDO(application),
                Wrappers.lambdaQuery(ApplicationDO.class).eq(ApplicationDO::getCode, application.getCode())) == 1;
    }

    @Override
    public Boolean delete(Application application) {
        return applicationMapper.delete(Wrappers.lambdaQuery(ApplicationDO.class).eq(ApplicationDO::getCode, application.getCode())) == 1;
    }

    @Override
    public Boolean existsCode(String applicationCode) {
        return applicationMapper.exists(Wrappers.lambdaQuery(ApplicationDO.class).eq(ApplicationDO::getCode, applicationCode));
    }

    @Override
    public Boolean existsName(String applicationName, String applicationCode) {
        List<ApplicationDO> applicationDOS = applicationMapper.selectList(Wrappers.lambdaQuery(ApplicationDO.class).eq(ApplicationDO::getName, applicationName));
        if (ObjectUtil.isEmpty(applicationDOS)) {
            return false;
        }
        return applicationDOS.stream().anyMatch(applicationDO -> !StringUtils.equals(applicationCode, applicationDO.getCode()));
    }

    @Override
    public Application query(String applicationCode) {
        ApplicationDO applicationDO = applicationMapper.selectOne(Wrappers.lambdaQuery(ApplicationDO.class).eq(ApplicationDO::getCode, applicationCode));
        return ApplicationToApplicationDOConverter.INSTANCE.applicationDOToApplication(applicationDO);
    }

    @Override
    public List<Application> list(String userId, ApplicationQuery applicationQuery) {
        return Collections.emptyList();
    }
}
